﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DNASequencing.core.Algorithms.rating
{
    class PolynomialRating : IRating
    {
        protected int z;
        protected double v;
        protected double n;

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="zeroPoint">Point in which function has value 0.</param>
        /// <param name="v">Value of the point <code>n - 1</code>.</param>
        /// <param name="n">Number of all oligonucleotides.</param>
        public PolynomialRating(int zeroPoint, double v, double n)
        {
            z = zeroPoint;
            this.v = v;
            this.n = n - 1;
        }

        protected double getValue(int arg, double p)
        {
            double a, b, c;

            b = ((3.0 / 4.0) * (z * z - 1) - (p * p - 1)) / ((z - 1) * (p - 1) * (p - z));
            a = ((-3.0 / 4.0) - b * (p - 1));
            c = 1 - b - a;

            return a * arg * arg + b * arg + c;
        }

        double IRating.rate(Oligonucleotide o)
        {
            for (int i = 0; i < o.next.Length; ++i)
                if (!o.used)
                {
                    int numberOfNext = o.next[i].Count;
                    if (numberOfNext <= z)
                        o.rating += (o.originalSequence.Length - 1 - i) * getValue(numberOfNext, (z - 1) / 2.0);
                    else
                        o.rating += (o.originalSequence.Length - 1 - i) * getValue(numberOfNext, (n - z) / 2.0);
                }

            int l = o.originalSequence.Length;
            o.rating += (l - o.error) * Math.Sqrt(l);

            return o.rating;
        }
    }
}
